use serde::{Deserialize, Deserializer, Serialize};
use snafu::{ResultExt, Snafu};
use std::borrow::Borrow;
use std::fmt::{Display, Formatter};
use url::{ParseError, Url};

/// 跳转链接
///
/// 当客户端需要换母包时，会引导玩家至跳转链接下载新的母包
#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(transparent)]
pub struct JumpUrl(Url);

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Failed to parse from string: {s} -> {source}"))]
    Parse { s: String, source: ParseError },
}

impl Display for JumpUrl {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", &self.0)
    }
}

impl JumpUrl {
    pub fn new(s: impl Borrow<str>) -> Result<Self, Error> {
        let s = s.borrow();
        Url::parse(s)
            .map(|url| JumpUrl(url))
            .context(ParseSnafu { s: s.to_string() })
    }
}

impl From<JumpUrl> for String {
    fn from(value: JumpUrl) -> Self {
        value.0.to_string()
    }
}
